﻿using GDM.Hogar.Aplicacion.Properties;
using GDM.Hogar.Entidades;
using GDM.Hogar.Entidades.Enums;
using GDM.Hogar.Managers.Contratos;
using GDM.Hogar.Soporte;
using GDM.Hogar.Soporte.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;

namespace GDM.Hogar.Aplicacion.Formularios.Actividades
{
    public partial class FrmActividad
#if DEBUG
 : AdaptadorFrm
#else
        : FrmBase
#endif
    {
        private readonly IActividadManager _actividadManager;
        private readonly IAgenteManager _agenteManager;

        private const int HorarioInicioActividades = 7; //- 07 hs
        private const int HorarioFinActividades = 20; //- 20 hs

        private IList<HorarioActividad> _horarios;

        private FlexBindingSource<HorarioActividad> _horariosBinding;

        private bool EsResponsable
        {
            get { return ContextoUsuario.RolId == (int)Rol.Responsable; }
        }

        public Action OnActividadCreada;
        public Action OnActividadActualizada;

        public FrmActividad(IActividadManager actividadManager, IAgenteManager agenteManager)
        {
            if (actividadManager == null)
                throw new ArgumentNullException("actividadManager");
            if (agenteManager == null)
                throw new ArgumentNullException("agenteManager");

            _actividadManager = actividadManager;
            _agenteManager = agenteManager;
            InitializeComponent();
        }

        public ConsultaActividad Actividad { get; set; }

        protected override string Titulo
        {
            get
            {
                return Actividad == null ? "Taller" : "Actividad";
            }
        }

        protected void GuardarRegistro()
        {
            if (!actividadValidator.Validate()) return;

            var desde = mtxtDesde.Text.Replace(":", "").Trim();
            var hasta = mtxtHasta.Text.Replace(":", "").Trim();
            if (!HorarioValido(desde, hasta)) return;

            if (Actividad != null)
            {
                //- Modo Edicion
                if (Actividad.Activa)
                {
                    if (!Actividad.Nombre.Trim().Equals(txtNombre.Text.Trim()))
                    {
                        if (_actividadManager.ExisteActividad(txtNombre.Text.Trim()))
                        {
                            MostrarMensajeError(string.Format(Resources.Actividad_Existe, txtNombre.Text.Trim()));
                            return;
                        }
                    }
                    ActualizarActividad();
                }
            }
            else
            {
                //- Modo Creacion
                if (_actividadManager.ExisteActividad(txtNombre.Text.Trim()))
                {
                    MostrarMensajeError(string.Format(Resources.Actividad_Existe, txtNombre.Text.Trim()));
                    return;
                }
                CrearActividad();
            }
        }

        private void ActualizarActividad()
        {
            var actividadHorarios = InstanciarActividad();
            actividadHorarios.Actividad.ActividadId = Actividad.ActividadId;
            actividadHorarios.Actividad.TipoActividadId = Actividad.TipoActividadId;
            try
            {
                string actividadAsXml = XmlHelper.GetXml(actividadHorarios);
                actividadAsXml = XmlHelper.RemoveAllNamespaces(actividadAsXml);
                _actividadManager.ActualizarActividad(actividadAsXml);
                MostrarMensajeExito(Resources.Actividad_GuardoConExito);
                if (OnActividadActualizada != null)
                {
                    OnActividadActualizada();
                }
            }
            catch (Exception ex)
            {
                MostrarMensajeError(Resources.GuardarActividad_Error);
            }
        }

        private void BindearCampos()
        {
            _horariosBinding = new FlexBindingSource<HorarioActividad>();
            _horariosBinding.CreateBinding(mtxtDesde, ctl => ctl.Text, data => data.HoraComienzo);
            _horariosBinding.CreateBinding(mtxtHasta, ctl => ctl.Text, data => data.HoraFin);
        }

        private void CrearActividad()
        {
            var actividadHorarios = InstanciarActividad();
            actividadHorarios.Actividad.TipoActividadId = (int)TipoActividad.Taller;
            try
            {
                string actividadAsXml = XmlHelper.GetXml(actividadHorarios);
                actividadAsXml = XmlHelper.RemoveAllNamespaces(actividadAsXml);
                _actividadManager.GuardarActividad(actividadAsXml);
                MostrarMensajeExito(Resources.Actividad_GuardoConExito);
                LimpiarControl(panel1);
                rbSemanalmente.Checked = true;
                if (OnActividadCreada != null)
                {
                    OnActividadCreada();
                }
                InicializarHorarios();
            }
            catch (Exception ex)
            {
                MostrarMensajeError(Resources.GuardarActividad_Error);
            }
        }

        private void CargarResponsables()
        {
            cmbResponsable.CargarItems(_agenteManager.ObtenerDocentes(), "NombreCompleto", "AgenteId", true, "-- Seleccione un Responsable --");
        }

        private void FrmActividad_Load(object sender, EventArgs e)
        {
            lstDias.DataBindings.Add("Enabled", rbSemanalmente, "Checked");
            RefrescarCambios = false;
            if (Actividad != null)
            {
                //- Modo Edicion
                cmbResponsable.Enabled = false;
                txtNombre.ReadOnly = true;
                if (Actividad.TipoActividadId == (int) TipoActividad.Taller)
                {
                    cmbResponsable.Enabled = true;
                    txtNombre.ReadOnly = false;
                    CargarResponsables();
                }
            }
            else
            {
                CargarResponsables();
            }
            BindearCampos();
            InicializarHorarios();
            if (Actividad == null)
            {
                return;
            }

            MostrarDatosActividad();
            if (!Actividad.Activa || !EsResponsable)
            {
                //- La actividad debe estar activa para poder editar sus datos
                HabilitarControl(panel1, false);
                btnGuardarAgente.Visible = false;
            }
        }

        private bool HorarioValido(string desde, string hasta)
        {
            epHorario.Clear();
            if (string.IsNullOrEmpty(desde))
            {
                if (string.IsNullOrEmpty(hasta)) return true;

                epHorario.SetError(mtxtDesde, "Ingrese una hora valida");
            }
            else
            {
                if (string.IsNullOrEmpty(hasta))
                    epHorario.SetError(mtxtHasta, "Ingrese una hora valida");
                else
                {
                    if (int.Parse(desde) > int.Parse(hasta))
                    {
                        epHorario.SetError(mtxtDesde, "La hora 'Desde' es mayor que la hora 'Hasta'");
                    }
                    else
                        return true;
                }
            }
            return false;
        }

        private void InicializarHorarios()
        {
            _horarios = null;
            if (Actividad == null)
            {
                _horarios = (from object diaSemana in Enum.GetValues(typeof(DiaSemana))
                             select new HorarioActividad { DiaSemanaId = (int)diaSemana, HoraComienzo = "", HoraFin = "" }).ToList();
            }
            else
            {
                _horarios = _actividadManager.ObtenerHorarios(Actividad.ActividadId);
                var horario = _horarios.FirstOrDefault();
                var diariamente = _horarios.All(x => x.HoraComienzo.Equals(horario.HoraComienzo) && x.HoraFin.Equals(horario.HoraFin));
                rbDiariamente.Checked = diariamente;
            }
            _horariosBinding.CurrentItem = _horarios[0];
        }

        private ActividadHorarios InstanciarActividad()
        {
            var actividad = new Actividad
                {
                    ResponsableId = cmbResponsable.SelectedIndex <= 0 ? default(int?) : ((ConsultaDocente)cmbResponsable.SelectedItem).AgenteId,
                    Nombre = txtNombre.Text.Trim(),
                    Activa = true
                };
            _horarios.ToList().ForEach(h =>
            {
                if (rbDiariamente.Checked)
                {
                    h.HoraComienzo = _horariosBinding.CurrentItem.HoraComienzo;
                    h.HoraFin = _horariosBinding.CurrentItem.HoraFin;
                }
                h.HoraComienzo = h.HoraComienzo.Trim(':');
                h.HoraFin = h.HoraFin.Trim(':');
            });
            return new ActividadHorarios { Actividad = actividad, Horarios = _horarios };
        }

        private void lstDias_SelectedIndexChanged(object sender, EventArgs e)
        {
            _horariosBinding.CurrentItem = _horarios[lstDias.SelectedIndex];
        }

        private void MostrarDatosActividad()
        {
            if (!string.IsNullOrEmpty(Actividad.Responsable.Trim()))
            {
                cmbResponsable.SelectedIndex = cmbResponsable.FindStringExact(Actividad.Responsable);
            }
            txtNombre.Text = Actividad.Nombre;
        }

        private bool EsHoraValida(string horaAValidar)
        {
            var hora = int.Parse(horaAValidar);
            return hora >= HorarioInicioActividades && hora <= HorarioFinActividades;
        }

        private bool SonMinutosValido(string minutosAValidar)
        {
            var minutos = int.Parse(minutosAValidar);
            return minutos >= 0 && minutos < 60;
        }

        private void mtxtDesde_Leave(object sender, EventArgs e)
        {
            var desde = mtxtDesde.Text.Replace(":", "").Trim();
            var hasta = mtxtHasta.Text.Replace(":", "").Trim();
            if (!string.IsNullOrEmpty(desde))
            {
                maskTextBox_Leave(sender, e);
                var hDesde = mtxtDesde.Text.Split(':');
                if (EsHoraValida(hDesde[0]) && SonMinutosValido(hDesde[1]))
                {
                    desde = mtxtDesde.Text.Replace(":", "").Trim();
                }
                else
                {
                    epHorario.SetError(mtxtDesde, "Ingrese una hora valida");
                    lstDias.Enabled = false;
                    return;
                }
            }
            else
            {
                mtxtDesde.Text = desde;
            }
            lstDias.Enabled = HorarioValido(desde, hasta) && rbSemanalmente.Checked;
        }

        private void mtxtHasta_Leave(object sender, EventArgs e)
        {
            var desde = mtxtDesde.Text.Replace(":", "").Trim();
            var hasta = mtxtHasta.Text.Replace(":", "").Trim();
            if (!string.IsNullOrEmpty(hasta))
            {
                maskTextBox_Leave(sender, e);
                var hHasta= mtxtHasta.Text.Split(':');
                if (EsHoraValida(hHasta[0]) && SonMinutosValido(hHasta[1]))
                {
                    hasta = mtxtHasta.Text.Replace(":", "").Trim();
                }
                else
                {
                    epHorario.SetError(mtxtHasta, "Ingrese una hora valida");
                    lstDias.Enabled = false;
                    return;
                }
            }
            else
            {
                mtxtHasta.Text = hasta;
            }
            lstDias.Enabled = HorarioValido(desde, hasta) && rbSemanalmente.Checked;
        }

        private void btnGuardarAgente_Click(object sender, EventArgs e)
        {
            GuardarRegistro();
        }

        private void actividadValidator_CustomValidation(object sender, Controles.Validador.Componentes.ValidationEventArgs e)
        {
            if (e.Control == cmbResponsable)
            {
                e.Valid = cmbResponsable.SelectedIndex > 0;
            }
        }
    }
}